import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_book/data/model/book_chapter_model.dart';
import 'package:flutter_book/page/book/controller/book_page_controller.dart';
import 'data/default_book_data.dart';
import 'util/touch_event.dart';
import 'package:get/get.dart';
import 'dart:ui' as ui;

import 'animation/controller_animation_with_listener_number.dart';
import 'book_reader/manager_reader_page.dart';
import 'book_reader/widget_reader_painter.dart';
import 'data/animation_type.dart';
import 'package:flutter_book/util/extensions/string_extensions.dart';

// ignore: must_be_immutable
class BookAnimationPage extends StatelessWidget {

  final BookAnimationPageController controller;

  BookAnimationPage({required this.controller});

  //滑动方向
  TouchEvent currentTouchEvent = TouchEvent(TouchEvent.ACTION_UP, null);

  @override
  Widget build(BuildContext context) {
    return GetBuilder<BookAnimationPageController>(
      init: controller,
      builder: (ctl) {
        return _getContentBox();
      },
    );
  }

  Widget _getContentBox() {
    return GetBuilder<BookAnimationPageController>(
      id: "updateData",
      builder: (ctl) => ctl.isLoading ? _getLoadingUi() : _getBody(),
    );
  }


  Widget _getBody() {
    return RawGestureDetector(
        gestures: <Type, GestureRecognizerFactory>{
          VerticalDragGestureRecognizer: GestureRecognizerFactoryWithHandlers<VerticalDragGestureRecognizer>(
                () => VerticalDragGestureRecognizer(),
                (VerticalDragGestureRecognizer instance) {
              instance
                ..onDown = (detail) {
                  // print("instance..onDown");
                  if(controller.isLoading)return;
                  if (currentTouchEvent.action != TouchEvent.ACTION_DOWN ||
                      currentTouchEvent.touchPos != detail.globalPosition) {
                    currentTouchEvent = TouchEvent(TouchEvent.ACTION_DOWN, detail.localPosition);
                    controller.mPainter.setCurrentTouchEvent(currentTouchEvent);
                    controller.canvasKey.currentContext?.findRenderObject()?.markNeedsPaint();
                  }
                };
              instance
                ..onUpdate = (detail) {
                  if(controller.isLoading)return;
                  // print("instance..onUpdate");
                  ///全局坐标转换为局部坐标
                  if (currentTouchEvent.action != TouchEvent.ACTION_MOVE ||
                      currentTouchEvent.touchPos != detail.globalPosition) {
                    currentTouchEvent = TouchEvent(TouchEvent.ACTION_MOVE, detail.globalPosition);

                    controller.mPainter.setCurrentTouchEvent(currentTouchEvent);
                    controller.canvasKey.currentContext?.findRenderObject()?.markNeedsPaint();
                  }
                };
              instance
                ..onEnd = (detail) {
                  if(controller.isLoading)return;
                  // print("instance..onEnd");
                  if (currentTouchEvent.action != TouchEvent.ACTION_UP ||
                      currentTouchEvent.touchPos != Offset(0, 0)) {
                    currentTouchEvent = TouchEvent<DragEndDetails>(TouchEvent.ACTION_UP, Offset(0, 0));
                    controller.mPainter.setCurrentTouchEvent(currentTouchEvent);
                    controller.canvasKey.currentContext?.findRenderObject()?.markNeedsPaint();
                  }
                };
            },
          ),
        },
        child: _getCustomPaint());
  }




  Widget _getLoadingUi(){
    return  Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Text(
            '加载中...',
            style: TextStyle(fontSize: 16.0),
          ),
          CircularProgressIndicator(
            strokeWidth: 1.0,
          )
        ],
      ),
    );
  }


  Widget _getCustomPaint(){
    return CustomPaint(
      key: controller.canvasKey,
      size: Size(Get.width + 5, Get.height + 5),
      isComplex: true,
      painter: controller.mPainter,
    );
  }
}

class BookAnimationPageController<T> extends GetxController{

  TickerProvider vsync;
  GlobalKey canvasKey;

  BookAnimationPageController(this.vsync, this.canvasKey);

  //是不是加载中
  bool isLoading = true;


  late BookPageController bookPageController;

  //画笔
  late NovelPagePainter mPainter;

  //管理器
  late ReaderPageManager pageManager;

  //动画
  late AnimationController animationController;

  //点击事件
  Function? onTap;

  //长按事件
  Function? onLongTap;

  //设置单击事件
  onTapListener(Function onTap){
    this.onTap=onTap;
  }

  //设置长按事件
  onLongTapListener(Function onLongTap){
    this.onLongTap=onLongTap;
  }


  ///设置动画类型[AnimationType]
  setAnimationType(int animationType) async {
    if (AnimationType.isAnimation(animationType)) {
      DefaultBookData.animationType = animationType;
      if (!isLoading) {
        await init();
        update(["updateData"]);
      }
    } else {
      "$animationType,不是已知的动画类型重新设置请".toastD;
    }
  }

  setBookContentController(BookPageController bookPageController, bool isLoading) async {
    this.bookPageController = bookPageController;
    this.isLoading = isLoading;
    if (!isLoading) {
      await init();
    }
    update(["updateData"]);
  }


  init() async {
    switch (DefaultBookData.animationType) {
      case AnimationType.TYPE_ANIMATION_SIMULATION_TURN:
      case AnimationType.TYPE_ANIMATION_COVER_TURN:
        animationController = AnimationControllerWithListenerNumber(vsync: vsync,);
        break;
      case AnimationType.TYPE_ANIMATION_SLIDE_TURN:
        animationController = AnimationControllerWithListenerNumber.unbounded(vsync: vsync,);
        break;
      default:
        animationController = AnimationControllerWithListenerNumber(vsync: vsync,);
    }
    pageManager = ReaderPageManager(
      animationType: DefaultBookData.animationType,
      canvasKey: canvasKey,
      animationController: animationController,
    );
    await pageManager.setBookContentController(bookPageController);
    pageManager.onTapListener(onTap);
    pageManager.onLongTapListener(onLongTap);
    mPainter = NovelPagePainter(pageManager: pageManager);
  }

  @override
  void dispose() {
    super.dispose();
    animationController.dispose();
  }
}

